import org.kwis.msp.lcdui.*;
import org.kwis.msp.lwc.*;
import java.lang.Character;
import java.util.Vector;

public class ScreenManager extends Card implements Runnable, GameConstants
{
	private boolean first = true;
	private boolean bEndThread = false;	
	private boolean dead = false;
	private boolean gameOver = false;
	private int paddleLife;
	
	private int initPaddleX, initPaddleY;
	private int initBallX, initBallY;

	private boolean startGame;
	private int currStage;

	private Paddle paddle;
	private Ball ball;
	private Block block;

	Thread thread = null;

	public ScreenManager()
	{
		startGame = false;
		currStage = 1;

		// Paddle과 Ball의 초기 위치를 잡아준다.
		initPaddleX = getWidth()/2-PADDLE_WIDTH/2;
		initPaddleY = getHeight()-10-PADDLE_HEIGHT;
		initBallX = getWidth()/2-BALL_RADIUS;
		initBallY = getHeight()-2-16-BALL_RADIUS;

		initElements();
	}

	// Ball, Paddle, Block을 초기화시킨다.
	private void initElements()
	{
		paddle = new Paddle(initPaddleX, initPaddleY);
		ball = new Ball(initBallX, initBallY );
		ball.initialize();
		block = new Block(currStage);
		paddleLife = LIFE;
	}

	public void paint(Graphics g)
	{
		// 처음에 타이틀화면을 그려준다.
		if (first) {
			paintTitleScreen(g);
		}
		// 게임오버 화면을 그려준다.
		else if(gameOver) {
			paintGameOver(g);			
		}
		// 게임화면을 그러준다.
		else { 
			g.setColor(0xffffff);
			g.fillRect(0,0,getWidth(),getHeight());

			paddle.paint(g);
			ball.paint(g);
			block.paint(g);

			// 스테이지가 바뀔때 스테이지를 표시해준다.
			if (startGame == false)
			{
				g.setColor(0x000000);
				g.drawString("S T A G E  "+currStage,25,100,Graphics.TOP);
			}
		}
	}

	public void run()
	{
		while(!bEndThread)
		{
			// 초기화면이 아니고 
			// 공을 놓쳐 죽은 상태가 아닐때
			// 공을 움직인후 충돌테스트를 해주고 repaint시켜준다.
			if(!dead) {
				ball.move();
				hitTest();
				repaint();
			}
			
			try
			{
				Thread.sleep(6);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	protected boolean keyNotify(int type, int key) 
	{
		// Game Over가 된경우 키입력을 받지 않게 한다.
		if(gameOver) return true;

		// 처음 실행할때 타이틀을 보여준후 키가 눌렸을때의 처리
		if(first) {
			first = false;
			repaint();
			return true;
		}
		
		// Stage 화면을 보여준후
		// 아무키나 입력을 받으면 시작하게 된다.
		else if(startGame == false && !dead && type == EventQueue.KEY_PRESSED)
		{
			startGame = true;
			if(currStage!=1) {
				bEndThread = false;
			}
			thread = new Thread(this);
			thread.start();
		}
		// 공을 놓쳐서 죽었을때
		else if(dead && type == EventQueue.KEY_PRESSED)
		{
			dead = false;
		}

		// 왼쪽, 오른쪽 키에대한 이벤트 처리
		switch(Display.getGameAction(key)) 
		{
			case EventQueue.LEFT : 
				paddle.moveLeft();
				break;
			case EventQueue.RIGHT : 
				paddle.moveRight();
				break;
		}
		if(type == EventQueue.KEY_PRESSED) { repaint(); }
		return true;
	}

	// 처음의 타이틀 화면을 그려준다.
	public void paintTitleScreen(Graphics g)
	{
		Image img = null;

		try
		{
			img = Image.createImage("title.png");	
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		g.drawImage(img,0,0,Graphics.TOP);
	}

	// 공과 벽, 공과 블록, 공과 paddle의 충돌테스트를 실행한다.
	private void hitTest()
	{
		wallHitTest();
		paddleHitTest();
		blockHitTest();
	}

	// 벽데대한 Hit Test
	private void wallHitTest()
	{
		int x = ball.getX();
		int y = ball.getY();

		if( x <= 0 ) {
			ball.setPosX(0);
			ball.inverseDeltaX();
		}

		if( x+BALL_DIAMETER >= MAX_WIDTH) {
			ball.setPosX(MAX_WIDTH - BALL_DIAMETER);
			ball.inverseDeltaX();
		}

		if( y <= 0 ) {
			ball.setPosY(0);
			ball.inverseDeltaY();
		}

		if( y+BALL_DIAMETER >= MAX_HEIGHT ) {
			// 생명이 하나 남아있는 상태에서 죽었다면
			// 게임오버가 된다.
			if(paddleLife == 1) {
				bEndThread = true;
				gameOver = true;
				repaint();
			}
			// 아닌경우 Paddle과 Ball의 위치를 
			// 초기화 시켜주고, 생명을 하나감소시킨후
			// 사용자 키입력을 기다리게 한다.
			else {
				dead = true;
				paddleLife--;

				ball.moveTo(initBallX,initBallY);
				paddle.paddleSetToPos(initPaddleX, initPaddleY);
			}
		}
	}

	// Paddle에 대한 Hit Test
	private void paddleHitTest()
	{
		int result = paddle.hitTest(ball.getX(),ball.getY());	

		if (result == PADDLE_HIT_NORMAL)	{
			ball.inverseDeltaY();
		}
		else if(result == PADDLE_HIT_EDGE) {
			ball.inverseDeltaX();
			ball.inverseDeltaY();
		}
	}

	// Block에 대한 Hit Test
	private void blockHitTest()
	{
		int result = block.hitTest(ball.getX(),ball.getY(),ball.getDeltaX(),ball.getDeltaY());	

		if (result == BLOCK_HIT_NORMAL)	{
			ball.inverseDeltaY();
		}
		else if(result == BLOCK_HIT_EDGE) {
			ball.inverseDeltaX();
			ball.inverseDeltaY();
		}
		else if(result == BLOCK_HIT_NOMOREBLOCKS)
		{
			goToNextStage();
		}
	}

	// GAME OVER 화면을 그려준다.
	private void paintGameOver(Graphics g)
	{
		g.setColor(0xffffff);
		g.fillRect(0,0,getWidth(),getHeight());
		g.setColor(0xff0000);
		g.drawString("G A M E  O V E R",15,60,Graphics.TOP);
	}

	// 다음 스테이지로 전환한다.
	private void goToNextStage()
	{
		bEndThread = true;

		// 현재의 스테이지가 마지막 스테이지 였으면
		// 게임오버
		if (currStage == STAGE_MAX)
		{
			gameOver = true;
		}
		// 아니면 계속 진행한다.
		else {
			currStage++;
			startGame = false;
			initElements();
		}
		repaint();
	}
};